package com.dabai.iot.core.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.dabai.common.core.enums.YnEnum;
import com.dabai.common.core.utils.DateUtils;
import com.dabai.common.core.utils.Func;
import com.dabai.common.core.utils.LocalDateUtils;
import com.dabai.iot.core.entity.DeviceCountEntity;
import com.dabai.iot.core.entity.DeviceEntity;
import com.dabai.iot.core.entity.ProductEntity;
import com.dabai.iot.core.service.*;
import com.dabai.iot.core.vo.HomeCountVO;
import com.dabai.iot.core.vo.HomeLineVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 首页统计服务实现类
 *
 * @author kev1n
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class HomeServiceImpl implements IHomeService {

    private final IProductService productService;
    private final IDeviceService deviceService;
    private final IDeviceCountService deviceCountService;
    private final IDeviceLogService deviceLogService;

    @Override
    public HomeCountVO countStatistics(String tenantId) {
        HomeCountVO vo = new HomeCountVO();

        // 查询产品数量
        List<ProductEntity> productList = productService.lambdaQuery()
            .eq(Func.isNotBlank(tenantId), ProductEntity::getTenantId, tenantId)
            .list();
        vo.setProductCount((long) productList.size());

        // 查询所有设备列表
        List<DeviceEntity> deviceList = deviceService.lambdaQuery()
            .eq(Func.isNotBlank(tenantId), DeviceEntity::getTenantId, tenantId)
            .list();
        vo.setDeviceCount((long) deviceList.size());

        // 当前在线设备数量
        Long onlineCount = deviceList.stream().filter(device -> YnEnum.YES.getValue().equals(device.getIsOnline())).count();
        vo.setOnlineCount(onlineCount);
        // 当前离线设备数量
        Long offlineCount = deviceList.stream().filter(device -> YnEnum.NO.getValue().equals(device.getIsOnline())).count();
        vo.setOfflineCount(offlineCount);

        // 查询昨日在线数量
        String yesterday = DateUtil.format(DateUtil.yesterday(), "yyyyMMdd");
        Long yesterdayCount = deviceCountService.getCount(tenantId, yesterday);
        vo.setYesterdayOnlineCount(yesterdayCount);

        // 统计今日设备消息量和当月设备消息量
        DateTime now = DateUtil.date();
        Date beginOfDay = DateUtil.beginOfDay(now).toJdkDate();
        Date endOfDay = DateUtil.endOfDay(now).toJdkDate();
        Date beginOfMonth = DateUtil.beginOfMonth(now).toJdkDate();
        Date endOfMonth = DateUtil.endOfMonth(now).toJdkDate();
        long todayMessageCount = 0;
        long monthMessageCount = 0;
        for (ProductEntity product : productList) {
            Long aLong = deviceLogService.deviceMessageCount(tenantId, product.getProductKey(), beginOfDay, endOfDay);
            todayMessageCount += aLong;
            Long bLong = deviceLogService.deviceMessageCount(tenantId, product.getProductKey(), beginOfMonth, endOfMonth);
            monthMessageCount += bLong;
        }
        vo.setTodayMessageCount(todayMessageCount);
        vo.setMonthMessageCount(monthMessageCount);

        return vo;
    }

    @Override
    public List<HomeLineVO> createDeviceStatistics(String tenantId, LocalDate startDate, LocalDate endDate) {
        return deviceService.getDeviceCountByCreateDate(tenantId, startDate, endDate);
    }

    @Override
    public List<HomeLineVO> onlineStatistics(String tenantId, LocalDate startDate, LocalDate endDate) {
        // 格式化日期
        String start = LocalDateUtils.formatDateMini(startDate);
        String end = LocalDateUtils.formatDateMini(endDate);

        // 查询日期间隔内在线设备数量
        List<DeviceCountEntity> deviceCountList = deviceCountService.lambdaQuery()
            .eq(DeviceCountEntity::getTenantId, tenantId)
            .ge(DeviceCountEntity::getDate, start)
            .le(DeviceCountEntity::getDate, end)
            .list();

        // 将查询结果转换为 Map 便于快速查找
        Map<String, Long> countMap = deviceCountList.stream()
            .collect(Collectors.toMap(
                DeviceCountEntity::getDate,
                DeviceCountEntity::getOnlineCount
            ));

        // 当 endDate 为今天时，查询缓存中的在线数量（今天的还未入库）
        if (LocalDate.now().equals(endDate)) {
            countMap.put(end, deviceCountService.getDeviceOnlineCount(tenantId, DateUtils.toDate(endDate)));
        }

        // 生成完整日期序列并补全 0 值
        return LocalDateUtils.getDateRange(startDate, endDate).stream()
            .map(date -> {
                HomeLineVO stat = new HomeLineVO();
                stat.setDateX(date);
                stat.setCountY(countMap.getOrDefault(LocalDateUtils.formatDateMini(date), 0L));
                return stat;
            })
            .collect(Collectors.toList());
    }

}


